Overview

During this pandemic, most of the reports which we get are often through the media. However, these reports tend to be inaccurate and inconsistent as they tend to cherry-pick the statistics and graphs to generate attention grabbing headlines. As such, to get an accurate and reliable picture of the current impact of COVID-19, we should pull the data directly from a reliable source and analyze it. In this report, we will obtain data directly from Our World in Data which relies on data from Johns Hopkins University and visualize them using the plotly and leaflet packages in R.

Load Packages

library(tidyverse)
library(leaflet)
library(lubridate)
library(plotly)
library(rgdal)

Load and Explore Data

# Load Data
data<-read_csv("https://covid.ourworldindata.org/data/owid-covid-data.csv")
glimpse(data)
## Rows: 79,479
## Columns: 59
## $ iso_code                              <chr> "AFG", "AFG", "AFG", "AFG", "...
## $ continent                             <chr> "Asia", "Asia", "Asia", "Asia...
## $ location                              <chr> "Afghanistan", "Afghanistan",...
## $ date                                  <date> 2020-02-24, 2020-02-25, 2020...
## $ total_cases                           <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,...
## $ new_cases                             <dbl> 1, 0, 0, 0, 0, 0, 0, 0, 1, 2,...
## $ new_cases_smoothed                    <dbl> NA, NA, NA, NA, NA, 0.143, 0....
## $ total_deaths                          <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_deaths                            <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_deaths_smoothed                   <dbl> NA, NA, NA, NA, NA, 0, 0, 0, ...
## $ total_cases_per_million               <dbl> 0.026, 0.026, 0.026, 0.026, 0...
## $ new_cases_per_million                 <dbl> 0.026, 0.000, 0.000, 0.000, 0...
## $ new_cases_smoothed_per_million        <dbl> NA, NA, NA, NA, NA, 0.004, 0....
## $ total_deaths_per_million              <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_deaths_per_million                <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_deaths_smoothed_per_million       <dbl> NA, NA, NA, NA, NA, 0, 0, 0, ...
## $ reproduction_rate                     <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ icu_patients                          <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ icu_patients_per_million              <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ hosp_patients                         <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ hosp_patients_per_million             <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ weekly_icu_admissions                 <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ weekly_icu_admissions_per_million     <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ weekly_hosp_admissions                <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ weekly_hosp_admissions_per_million    <lgl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_tests                             <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ total_tests                           <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ total_tests_per_thousand              <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_tests_per_thousand                <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_tests_smoothed                    <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_tests_smoothed_per_thousand       <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ positive_rate                         <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ tests_per_case                        <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ tests_units                           <chr> NA, NA, NA, NA, NA, NA, NA, N...
## $ total_vaccinations                    <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ people_vaccinated                     <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ people_fully_vaccinated               <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_vaccinations                      <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_vaccinations_smoothed             <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ total_vaccinations_per_hundred        <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ people_vaccinated_per_hundred         <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ people_fully_vaccinated_per_hundred   <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ new_vaccinations_smoothed_per_million <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ stringency_index                      <dbl> 8.33, 8.33, 8.33, 8.33, 8.33,...
## $ population                            <dbl> 38928341, 38928341, 38928341,...
## $ population_density                    <dbl> 54.422, 54.422, 54.422, 54.42...
## $ median_age                            <dbl> 18.6, 18.6, 18.6, 18.6, 18.6,...
## $ aged_65_older                         <dbl> 2.581, 2.581, 2.581, 2.581, 2...
## $ aged_70_older                         <dbl> 1.337, 1.337, 1.337, 1.337, 1...
## $ gdp_per_capita                        <dbl> 1803.987, 1803.987, 1803.987,...
## $ extreme_poverty                       <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ cardiovasc_death_rate                 <dbl> 597.029, 597.029, 597.029, 59...
## $ diabetes_prevalence                   <dbl> 9.59, 9.59, 9.59, 9.59, 9.59,...
## $ female_smokers                        <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ male_smokers                          <dbl> NA, NA, NA, NA, NA, NA, NA, N...
## $ handwashing_facilities                <dbl> 37.746, 37.746, 37.746, 37.74...
## $ hospital_beds_per_thousand            <dbl> 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,...
## $ life_expectancy                       <dbl> 64.83, 64.83, 64.83, 64.83, 6...
## $ human_development_index               <dbl> 0.511, 0.511, 0.511, 0.511, 0...

To visualize the most updated data, we shall use a Choropleth Map to show the number of events (e.g. Cases, Deaths etc.) for each country.

data_today<-data %>%
  filter(date==today()-2) %>%
  filter(!str_detect(iso_code, "OWID"))

plot_ly(type="choropleth",
        locations=data_today$iso_code,
        z=data_today$total_cases,
        text=data_today$location,
        color=data_today$total_cases, 
        colors="Reds") %>%
  colorbar(title="Number of Cases", 
           y=0.75) %>%
  layout(title=list(text=paste0("Number of COVID-19 cases as of ", today()-2), y=0.9))

Using the leaflet package, we can visualize the data in a similar fashion. We start by first downloading the shapefile and loading the data.

if(!file.exists("Data/TM_WORLD_BORDERS_SIMPL-0.3.shp")){
  download.file("http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip", 
              destfile="Data/world_shape_file.zip")
}

world<-readOGR( 
  dsn=paste0(getwd(), "/Data"), 
  layer="TM_WORLD_BORDERS_SIMPL-0.3",
  verbose=FALSE
)

# Replace world_spdf@data with our data
world@data<-world@data %>% 
  select(ISO3) %>% 
  rename(iso_code=ISO3) %>% 
  left_join(data_today, by="iso_code")

We shall now plot the choropleth.

mybins<-c(0, 10000, 50000, 100000, 500000, 10000000, 20000000, 40000000)
mypal<-colorBin( palette="YlOrRd", domain=world@data$total_cases, na.color="transparent", bins=mybins)

mytext<-paste(
    "Country: ", world@data$location,"<br/>", 
    "Total Cases: ", world@data$total_cases, "<br/>", 
    "Total Deaths: ", world@data$total_deaths, "<br/>",
    "Population: ", round(world@data$population, 2), 
    sep="") %>%
  lapply(htmltools::HTML)

leaflet(world) %>% 
  addTiles() %>%
  addPolygons(fillColor=~mypal(total_cases), 
              stroke=TRUE, 
              fillOpacity=0.9,
              color="white", 
              smoothFactor=0.5,
              weight=0.3, 
              label=mytext, 
              labelOptions=labelOptions( 
      style = list("font-weight" = "normal", padding = "3px 8px"), 
      textsize = "13px", 
      direction = "auto"
    )
  ) %>% 
  addLegend(pal=mypal, 
            values=~total_cases, 
            opacity=0.9, 
            title=paste0("Number of Cases as of ", today()-2), 
            position="bottomleft")